package com.cloud.punish.workflow.service.impl;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cloud.punish.interfaces.FeignClientFreeflow;
import com.cloud.punish.workflow.bean.WfActEvent;
import com.cloud.punish.workflow.command.Command;
import com.cloud.punish.workflow.command.WfRequest;
import com.cloud.punish.workflow.command.WfResponse;
import com.cloud.punish.workflow.command.finish.FinishCommand;
import com.cloud.punish.workflow.command.finish.FinishRequest;
import com.cloud.punish.workflow.command.rollback.RollbackCommand;
import com.cloud.punish.workflow.command.rollback.RollbackRequest;
import com.cloud.punish.workflow.command.transit.TransitCommand;
import com.cloud.punish.workflow.command.transit.TransitRequest;
import com.cloud.punish.workflow.handler.Handler;
import com.cloud.punish.workflow.handler.HandlerChain;
import com.cloud.punish.workflow.handler.common.ActTimeCalculationHandler;
import com.cloud.punish.workflow.handler.common.OverTimeLogHandler;
import com.cloud.punish.workflow.service.WorkflowCoreService;

@Service
@Transactional
public class WorkflowCoreServiceImpl implements WorkflowCoreService, ApplicationContextAware {
	private static final Logger logger = LoggerFactory.getLogger(WorkflowCoreServiceImpl.class);

	private ApplicationContext applicationContext;

	@Autowired
	private FeignClientFreeflow feignClientFreeflow;

	@Override
	public void execute(WfRequest request, WfResponse response, Command command) {
		HandlerChain chain = new HandlerChain();
		chain.setApplicationContext(applicationContext);
		// 指令执行计时
		chain.addHandler(new OverTimeLogHandler());
		// 环节计时
		chain.addHandler(new ActTimeCalculationHandler());
		long actDefId = 0;
		// 批转事件
		if (command instanceof TransitCommand){
			TransitRequest req = (TransitRequest)request;
		}
		// 回退事件
		if (command instanceof RollbackCommand) {
			RollbackRequest req = (RollbackRequest)request;
		}
		// 办结事件
		if (command instanceof FinishCommand) {
			FinishRequest req = (FinishRequest)request;
		}
		if(actDefId > 0){
			List<WfActEvent> events = feignClientFreeflow.loadProcActEvents(actDefId);
			if (events.size() > 0) {
				try {
					for (WfActEvent event : events) {
						Class<?> clazz = Class.forName(event.getEventClazz());
						String params = event.getEventParam();
						if (StringUtils.isEmpty(params)) {
							chain.addHandler((Handler) clazz.getConstructor().newInstance());
						} else {
							chain.addHandler((Handler) clazz.getConstructor(String.class).newInstance(params));
						}
					}
				} catch (Exception e) {
					logger.error("流程");
					throw new RuntimeException("流程事件配置错误", e);
				}
			}
		}
		// 指令事件
		chain.command(command);
		chain.doHandler(request, response);
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
}
